Within-host diversity and minor variant analyses in samples from Houston Methodist Hospital, 2021

Sample characteristics and inclusion criteria


##### Load libraries and define recurring functions / variables
source("./scripts/startup.R")

#all mcov samples we have ever received - reformat sample names to be consistent
mcov_samples_all <- fread("full_lineage_report_20220507.tsv", data.table=F) %>% 
  mutate(MCoVNumber=mcov_reformat(taxon)) %>% 
  filter(startsWith(MCoVNumber, "MCoV")) %>% 
  filter(MCoVNumber!="MCoV30904") #remove one sample with inconsistently formatted duplicates

#run and date info; keep only earliest sample from the same patient
mcov_info <- fread("sample_date_and_run.csv", data.table=F) %>% 
  mutate(COLLECTION_DT=as.Date(COLLECTION_DT, "%m/%d/%y"), 
         MCoVNumber=str_remove(mcov_id, "-")) %>% 
  arrange(COLLECTION_DT) %>% filter(!duplicated(PatientID))

#samples we received that we're interested in (December 2020-November 2021)
mcov_samples_1 <- mcov_samples_all %>% filter(!taxon %in% dup65.66) %>% 
  filter(MCoVNumber %in% mcov_info$MCoVNumber) %>% left_join(mcov_info)
Joining, by = "MCoVNumber"
#all samples sequenced in each run (including those from outside of this study period) -- sometimes relevant for run QC purposes
runs_all_samples <- fread("run_samples.csv", data.table = F) %>% 
  mutate(MCoVNumber=str_remove(`Sample ID`,"-"), run=Run) %>% 
  select(run, MCoVNumber)

#summary stats on coverage of each sample; drop the run 65 duplicates and join coverage info to main dataset
d1 = fread('coverage_levels_20220507.csv', data.table = F) %>% 
  filter(duplicated(samplename)) %>% pull(samplename)
d2 = fread('coverage_levels_20220507.csv', data.table = F) %>% 
  filter(samplename %in% d1) %>% filter(!duplicated(samplename)) %>% 
  pull(filename)
coverage_levels <- fread('coverage_levels_20220507.csv', data.table = F) %>% 
  filter(!filename %in% d2) %>% filter(samplename!="MCoV30904") %>% select(-1)
# join dataframes
mcov_samples<-mcov_samples_1 %>% 
  select(MCoVNumber, lineage, scorpio_call, qc_status, 
         COLLECTION_DT, INSTRUMENT, INSTRUMENT_RESULT, run=run_group) %>% 
  left_join(coverage_levels, by=c("MCoVNumber"="samplename"))

mcov_samples_with_ct<-mcov_samples %>% filter(INSTRUMENT_RESULT<50) %>% 
  mutate(CT=INSTRUMENT_RESULT)
#what's the relationship between CT value and read coverage?
coverage_all<-mcov_samples_with_ct %>% ggplot(aes(x=CT, y=median_coverage)) + 
  geom_point(alpha=0.07) + theme_bw() + xlab("Ct value") + ylab("Sample median depth")
#how does coverage in high-CT samples compare with the rest of them?
coverage_ct_cat<-mcov_samples_with_ct %>% mutate(sample_ct=if_else(CT>=40, "CT>=40", "CT<40")) %>% 
  ggplot(aes(x=sample_ct, y=median_coverage)) + 
  geom_point(alpha=0.2, position=position_jitter(width=0.25)) + 
  geom_boxplot(color="red", alpha=0) + theme_bw() + 
  xlab("Ct value") + ylab("Sample median depth")
#see that CT>=40 samples tend to have extremely low coverage, but some outliers
#SUPP FIG 12
#coverage_pre_filtering<-plot_grid(coverage_all, coverage_ct_cat)
#coverage_pre_filtering

Run-level QC

#are there any runs where high-CT samples have unusually high coverage? treat CT>40 samples as negative controls and eliminate runs where their coverage is not different from those of the rest of the samples
test_group<-mcov_samples_with_ct %>% mutate(is_neg=if_else(CT>=40,1,0)) %>% 
  group_by(run) %>% mutate(n_negs=sum(is_neg)) %>% filter(n_negs>=3) %>% 
  ungroup() %>% mutate(sampletype=if_else(is_neg==1, "negctrl","sample"))
runs_to_drop1 = test_group %>% group_by(run) %>% 
  summarise(t_test_p=t.test(fraction_1000x_coverage~sampletype)$p.value) %>% 
  arrange(desc(t_test_p)) %>% filter(t_test_p>0.01) %>% pull(run)
runs_to_drop2 = test_group %>% group_by(run) %>% 
  summarise(t_test_p=t.test(median_coverage~sampletype)$p.value) %>% 
  arrange(desc(t_test_p)) %>% filter(t_test_p>0.01) %>% pull(run)

############ 
runs_to_drop<-union(runs_to_drop1, runs_to_drop2)

mcov_samples_with_ct %>% pull(run) %>% unique()
 [1] "Run_11" "Run_12" "Run_15" "Run_13" "Run_16" "Run_18" "Run_19" "Run_20" "Run_21" "Run_22" "Run_23" "Run_24" "Run_25" "Run_26" "Run_27"
[16] "Run_28" "Run_29" "Run_30" "Run_31" "Run_35" "Run_32" "Run_33" "Run_34" "Run_37" "Run_36" "Run_39" "Run_40" "Run_41" "Run_43" "Run_44"
[31] "Run_46" "Run_48" "Run_49" "Run_51" "Run_52" "Run_53" "Run_57" "Run_58" "Run_59" "Run_61" "Run_62" "Run_63" "Run_64" "Run_65" "Run_66"
[46] "Run_68" "Run_69" "Run_70" "Run_71" "Run_72" "Run_73" "Run_74" "Run_75" "Run_76" "Run_77" "Run_78" "Run_79" "Run_80" "Run_81" "Run_82"
[61] "Run_83" "Run_85" "Run_86" "Run_87" "Run_88" "Run_89" "Run_90" "Run_14" "Run_17"
test_group %>% group_by(run, sampletype) %>% summarize(counts = n()) %>% 
  filter(run %in% runs_to_drop) %>% nrow()
[1] 44
mcov_samples_with_ct %>% pull(run) %>% unique()
 [1] "Run_11" "Run_12" "Run_15" "Run_13" "Run_16" "Run_18" "Run_19" "Run_20" "Run_21" "Run_22" "Run_23" "Run_24" "Run_25" "Run_26" "Run_27"
[16] "Run_28" "Run_29" "Run_30" "Run_31" "Run_35" "Run_32" "Run_33" "Run_34" "Run_37" "Run_36" "Run_39" "Run_40" "Run_41" "Run_43" "Run_44"
[31] "Run_46" "Run_48" "Run_49" "Run_51" "Run_52" "Run_53" "Run_57" "Run_58" "Run_59" "Run_61" "Run_62" "Run_63" "Run_64" "Run_65" "Run_66"
[46] "Run_68" "Run_69" "Run_70" "Run_71" "Run_72" "Run_73" "Run_74" "Run_75" "Run_76" "Run_77" "Run_78" "Run_79" "Run_80" "Run_81" "Run_82"
[61] "Run_83" "Run_85" "Run_86" "Run_87" "Run_88" "Run_89" "Run_90" "Run_14" "Run_17"
test_group %>% group_by(run, sampletype) %>% summarize(counts = n()) %>% 
  filter(sampletype=="negctrl") %>% arrange(counts) %>% mutate(dropped = run %in% runs_to_drop) %>%
  ggplot(aes(dropped,counts, label=run)) + geom_boxplot() + geom_point() + geom_text_repel() + theme_pubr()


runs_kept = mcov_samples_with_ct$run[!mcov_samples_with_ct$run %in% runs_to_drop] %>% unique()
# for (i in runs_kept) {
#   f = mcov_samples_with_ct %>% filter(run == i) %>% ggplot(aes(INSTRUMENT_RESULT, fraction_1000x_coverage)) + geom_point() + ggtitle(i) + theme(plot.title = element_text(size = 40, face = "bold"))
#   print(f)
# }
f1 = mcov_samples_with_ct %>% ggplot(aes(INSTRUMENT_RESULT, fraction_1000x_coverage)) + 
  geom_point(shape=".", alpha = 0.5) + theme_pubr() + 
  theme(plot.title = element_text(size = 40, face = "bold")) + 
  geom_vline(xintercept=40, color = "red")
f1 = ggMarginal(f1 + rremove("xlab"))

f2 = mcov_samples_with_ct %>% ggplot(aes(INSTRUMENT_RESULT, log10(median_coverage))) + 
  geom_point(shape=".", alpha = 0.5) + theme_pubr() + 
  theme(plot.title = element_text(size = 40, face = "bold")) + 
  geom_vline(xintercept=40, color = "red")
f2 = ggMarginal(f2)

ggarrange(f1, f2, ncol = 1, nrow = 2, align = "v")

# tmp = data.table(mcov_samples_with_ct %>% filter(CT>35))[ , invisible(cor.test(fraction_1000x_coverage, -CT, method="spearman")[-2]), by=run] %>% select(run, p.value, estimate) %>%
#   mutate; tmp
# tmp = tmp %>% mutate(abnormal = run %in%   
#        c("Run_20","Run_89","Run_21","Run_58","Run_76","Run_71","Run_75",
#        "Run_86","Run_74","Run_70","Run_78","Run_62","Run_13","Run_85",
#        "Run_65","Run_34","Run_87","Run_11","Run_83","Run_16","Run_77",
#        "Run_81"))
# ggplot(tmp, aes(estimate, -log10(p.value), color = abnormal, 
#                 label = gsub("Run_", "", run))) + 
#          geom_point() + geom_text_repel()+ theme_pubr()
# 
# tmp %>% arrange(-p.value)
# # runs 2
### plot boxplot of the runs
stmp = mcov_samples_with_ct %>% mutate(abnormal = run %in%   
    runs_to_drop) %>% mutate(run = gsub("Run_", "", run)) %>% 
    mutate(is_neg=if_else(CT>=40,1,0))

f3 = ggplot(stmp, aes(run, fraction_1000x_coverage, color = abnormal, fill = abnormal)) + 
  geom_boxplot() + 
  geom_point(data = stmp %>% filter(is_neg == T), 
             aes(run, fraction_1000x_coverage), color = "red", alpha = .9, 
             shape = 1) + 
  scale_fill_grey(start = 1, end = 0.8) + 
  scale_color_grey(start=0, end=0.6) +
  theme(axis.text.x = element_text(angle = 90, hjust = 1), 
        text = element_text(size=8)) +
  labs( x = NULL)
  
f4 = ggplot(stmp, aes(run, log10(median_coverage), 
                      color = abnormal, fill = abnormal)) + 
  geom_boxplot() + 
  geom_point(data = stmp %>% filter(is_neg == T), 
             aes(run, log10(median_coverage)), color = "red", alpha = .9, 
             shape = 1) + 
  scale_fill_grey(start = 1, end = 0.8) + 
  scale_color_grey(start=0, end=0.6) +
  theme(axis.text.x = element_text(angle = 90, hjust = 1), 
        text = element_text(size=8))
  
ggarrange(f3, f4, ncol = 1, nrow = 2, align = "v", common.legend = T)

Sample-level QC

#nextclade QC
nc<-fread("houston_nextclade.tsv", sep='\t', data.table = F) %>% 
  mutate(MCoVNumber=regmatches(seqName, regexpr("[M,R,S,O]CoV.[0-9]+", seqName)) %>% 
           str_remove("-") %>% str_remove("_")) %>% filter(!duplicated(MCoVNumber))
nextclade_bad_samples<-nc %>% filter(qc.overallStatus %in% c("bad")) %>% pull(MCoVNumber)
#drop bad runs and samples that don't pass pangolin QC or nextclade QC
mcov_samples_filtered<-mcov_samples %>% filter(!run %in% runs_to_drop) %>% 
  filter(qc_status=="pass") %>% filter(!MCoVNumber %in% nextclade_bad_samples) %>% 
  filter(scorpio_call!="Omicron (BA.1-like)") %>% 
 ##### #main coverage criterion for fair comparisons: X depth over Y percent of the genome
  filter(fraction_100x_coverage>=0.98) %>% droplevels()

#what's the distribution of CT values?
ct_distribution_after_qc<-mcov_samples_filtered %>% filter(INSTRUMENT_RESULT<50) %>% 
  ggplot(aes(x=INSTRUMENT_RESULT)) + geom_histogram(binwidth=1) + theme_bw() + 
  xlab("Ct value") + labs(caption="After exclusion criteria")
nrow(mcov_samples_filtered %>% filter(INSTRUMENT_RESULT < 26))
[1] 6140
ggsave("ggsave/plot1_ct_before_after.pdf", plot1_ct_before_after, height = 3, width = 4)
Error in plot_theme(plot) : object 'plot1_ct_before_after' not found

Preliminary minor variant distributions

#nucleotide positions of all primers used in dataset; will exclude 
primers = fread("nCoV-2019.artic_v3.primer.txt", sep="\t", header=FALSE, data.table=F) %>% 
  select(start = V2, end = V3)
primer_positions_v3<-as.numeric()
for (i in 1:nrow(primers)){
  primer_positions_v3<-c(primer_positions_v3, primers[i,]$start:primers[i,]$end)
}

primers = fread("nCoV-2019.artic_v4.primer.bed", sep="\t", 
                header=FALSE, data.table = F) %>% select(start = V2, end = V3)
primer_positions_v4<-as.numeric()
for (i in 1:nrow(primers)){
  primer_positions_v4<-c(primer_positions_v4, primers[i,]$start:primers[i,]$end)
}

primers = fread("V4.1.bed", sep="\t", header=FALSE, data.table=F) %>% 
  select(start = V2, end = V3)
primer_positions_v4.1 <- as.numeric()
for (i in 1:nrow(primers)){
  primer_positions_v4.1 <- c(primer_positions_v4.1, primers[i,]$start:primers[i,]$end)
}

primer_positions_all <- c(primer_positions_v3, primer_positions_v4, primer_positions_v4.1) %>% unique()

#reference genome with nucleotide positions of genes
genes <- fread("ntpos_gene_update.csv", data.table = F)
gene_names <- genes %>% pull(gene_id) %>% unique()
genes$gene_id <- factor(genes$gene_id, levels = gene_names)
### Update this if you change sample inclusion criteria
#minor_variant_sites_allLevels <- fread("minor_sites_100x_all_20220507.csv", data.table=F) %>% mutate(MCoVNumber=regmatches(name, #regexpr("[M,R,S,O]CoV.[0-9]+", name)) %>% str_remove("-") %>% str_remove("_")) %>% filter(MCoVNumber %in% #mcov_samples_filtered$MCoVNumber)
#write.csv(minor_variant_sites_allLevels, "minor_sites_workingsamples_100-98minimum.csv", row.names=FALSE)
### Update this if change the thresholds for counting minor variants
#file was already filtered to sites with minimum 100 reads depth and A,C,T,G minor variant present and binomial significance check passed. Further filtering:
#depth_at_site<-100
#minor_frequency<-0.01
#total_minor_reads<-50
#
#minor_variant_sites_threshold_applied<-fread("minor_sites_workingsamples_100-98minimum.csv", data.table = F) %>%
#  filter(totalcount>=depth_at_site) %>%
#  filter(!ntpos %in% 1:265) %>% filter(!ntpos>29674) %>% #don't include 5' and 3' UTR
#  filter(!ntpos %in% primer_positions_all) %>% #don't include primer binding sites
#  filter(major %in% c("A","C","T","G")) %>% #don't want minor variants at consensus deletion sites
#  filter(minorfreq>=minor_frequency) #%>%
#  #filter(minorfreq*totalcount>=total_minor_reads) 

#write.csv(minor_variant_sites_threshold_applied, 'minor_variants_filtered_100x0.01_50.csv')
#load file that was generated/saved above
minor_variant_sites_threshold <- fread('minor_variants_filtered_100x0.01_50.csv', data.table=F) 
minor_variant_sites_threshold %>% pull(MCoVNumber) %>% unique %>% length
[1] 14536

Overall minor variant richness

n_var <- minor_variant_sites_threshold %>% group_by(MCoVNumber) %>% tally() %>% arrange(desc(n)) #this tally doesn't include any samples with 0 variants, so need to join to original list
samples_n_var <- mcov_samples_filtered %>% left_join(n_var) %>% arrange(COLLECTION_DT) %>% mutate(n_var=tidyr::replace_na(n,0)) 
Joining, by = "MCoVNumber"
#what's the distribution of minor variant richness?
### 
((
  n_var_select <- samples_n_var %>% ggplot(aes(x=n_var)) + 
  geom_histogram(binwidth=5) + theme_pubr() + 
  xlab("No. minor variants in sample") + ylab("No. samples") + 
  scale_y_continuous(trans='log1p', breaks=c(1, 10, 100, 1000, 5000))
))

ggsave("ggsave/plot1_target.pdf", plot = plot1_target, height = 4, width = 4)
Error in plot_theme(plot) : object 'plot1_target' not found
# test_ct = patient_data %>% filter(INSTRUMENT_RESULT<40) %>% mutate(vaccine = if_else(Vaccine_Status=="No vaccine", 0, 1)) %>% ggplot(aes(x=INSTRUMENT_RESULT, y=n_var, color = as.factor(vaccine))) + geom_point(shape = 1, alpha = 1/8) + geom_density_2d(alpha = 1/2) + scale_y_continuous(trans = "log2", breaks = c(0,1,2,4,8,16,32,64, 128, 256))+
#   scale_x_continuous(breaks = seq(0,40,by = 5)) +
#   theme_pubr() + xlab("Ct value") + ylab("No. minor variants") + geom_smooth(method=lm)
# ggMarginal(test_ct, groupColour = TRUE, groupFill = TRUE, type = "violin", draw_quantiles = c(.5))
# ggdraw(n_var_select + theme_half_open(12)) +
#    draw_plot(n_var_ct_zoom, x=0.3, y=0.3, width=0.7, height=0.7) +
#    draw_plot_label(
#      c("a", "b"),
#      c(0, 0.3),
#      c(1, 1),
#      size = 12
#    )
samples_n_var %>% pull(n_var) %>% summary()
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   0.00    3.00    6.00   18.94   16.00  452.00 

Reproducibility of minor variants

all_replicates_table_filt <- fread("replicated_samples.csv", data.table=F) %>% filter(MCoVNumber %in% samples_n_var$MCoVNumber)
|--------------------------------------------------|
|==================================================|
minors_table<-all_replicates_table_filt %>% 
  filter(major.original %in% c("A","C","T","G")) %>% 
  filter(minor.original %in% c("A","C","T","G")) %>%
  filter(totalcount.original>=100 & minorfreq.original>=0.01 & totalcount.original*minorfreq.original>=50 & 
           tolower(binocheck.original)!="false") %>% filter((!ntpos %in% primer_positions_all)) %>% 
  filter(!ntpos %in% 1:265) %>% filter(!ntpos>29674)
#was the same minor variant found in the second replicate? if not, set minor frequency to 0 in second rep
minors_table<-minors_table %>% 
  mutate(minorfreq.reseq=if_else(minor.original==minor.reseq, minorfreq.reseq, 0)) %>% 
  mutate(detected_minor_in_repl=if_else(minor.original==minor.reseq,"yes","no"))
#how well are minor variants recovered in samples with different Ct values?
minors_table <- minors_table %>% left_join(select(mcov_samples, MCoVNumber, CT=INSTRUMENT_RESULT)) %>% 
  mutate(sampleCT_bin = case_when(CT<26 ~ "below 26",
                                CT>=26&CT<=35 ~"CT 26-35",
                                CT>35&CT<50 ~"greater than 35",
                                CT>100~"unknown", #aptima instrument uses RLU not CT
                                is.na(CT) ~ "unknown")) 
Joining, by = "MCoVNumber"
((
  rep_ct<-minors_table %>% 
  ggplot(aes(x=minorfreq.original, y=minorfreq.reseq, color=detected_minor_in_repl)) + 
  scale_color_manual(values=c("red","black")) + geom_point(alpha=0.5) + 
  facet_wrap(~sampleCT_bin) + theme_bw() + labs(x="MAF in replicate 1", y="MAF in replicate 2") + 
  theme(legend.position="bottom")
))

#how well are minor variants recovered in samples with different median coverage?
rep_depth <- minors_table %>% left_join(coverage_levels, by=c("MCoVNumber"="samplename")) %>% 
  mutate(coverage_bin=cut(median_coverage, 4)) %>% 
  ggplot(aes(x=minorfreq.original, y=minorfreq.reseq, color=detected_minor_in_repl)) + 
  scale_color_manual(values=c("red","black")) + geom_point(alpha=0.5) + 
  facet_wrap(~coverage_bin) + theme_bw() + 
  labs(x="MAF in replicate 1", y="MAF in replicate 2") + 
  theme(legend.position="none", axis.text.x = element_text(color=c(1,0,1,0))) + 
  labs(caption="Reproducibility in samples with different median depths")
Warning: Vectorized input to `element_text()` is not officially supported.
ℹ Results may be unexpected or may change in future versions of ggplot2.
#in the range of Ct values/coverage observed here, reproducibility seems more associated with Ct than with coverage 
#what's the distribution of depth/MAF in reproducible vs. non-reproducible minor variants?
rep_depth_freq <- minors_table %>% ggplot(aes(x=totalcount.original, y=minorfreq.original)) + 
  geom_point(alpha=0.5) + facet_grid(detected_minor_in_repl~.) + theme_bw() + 
  theme(axis.text.x = element_text(color=c(1,0,1,0))) + xlab("Seq depth in rep 1") + 
  ylab("MAF in rep 1") + labs(caption="Reproducibility at sites with different depth and MAF")
Warning: Vectorized input to `element_text()` is not officially supported.
ℹ Results may be unexpected or may change in future versions of ggplot2.
#depth and frequency of minor variants is also not very different between reproducible and non-reproducible variants
rep_mutations <- minors_table %>% filter(detected_minor_in_repl=="yes") 
nonrep_mutations <- minors_table %>% filter(detected_minor_in_repl=="no") 

a <- table(rep_mutations$major.original, rep_mutations$minor.original) %>% 
  data.frame() %>% ggplot(aes(x=Var1, y=Var2, fill=Freq)) + 
  geom_tile(colour = "black") + # grid colour
  scale_fill_gradient(low = "white",
                      high = "steelblue") +
  theme_minimal() + labs(fill = "Number",
       x = "Consensus allele",
       y = "Minor allele", caption="Reproducible minor variants")

b <- table(nonrep_mutations$major.original, nonrep_mutations$minor.original) %>% 
  data.frame() %>% ggplot(aes(x=Var1, y=Var2, fill=Freq)) + 
  geom_tile(colour = "black") + 
  scale_fill_gradient(low = "white",
                      high = "steelblue") +
  theme_minimal() + labs(fill = "Number",
       x = "Consensus allele",
       y = "Minor allele", caption="Non-reproducible minor variants")

rep_nucleotides <- cowplot::plot_grid(a, b, ncol=2)

#SUPP FIG 8
rep_nucleotides

rep_indiv_samples <- minors_table %>% ggplot(aes(x=minorfreq.original, 
                                               y=minorfreq.reseq, 
                                               color=detected_minor_in_repl)) + 
  geom_point(alpha=0.5) + scale_color_manual(values=c("red","black")) + 
  facet_wrap(CT~MCoVNumber) + theme_bw() + xlab("MAF in replicate 1") + 
  ylab("MAF in replicate 2") + 
  theme(legend.position="none", axis.text.x = element_text(color=c(1,0,1,0)))
Warning: Vectorized input to `element_text()` is not officially supported.
ℹ Results may be unexpected or may change in future versions of ggplot2.
#SUPP FIG 1
plot_grid(
  plot_grid(rep_ct, 
            plot_grid(rep_depth, rep_depth_freq, ncol=2, rel_widths=c(1.2,1), 
                      labels=c("b","c")), nrow=2, labels=c("a",NA)), 
  rep_indiv_samples, labels=c(NA, "d"), rel_widths=c(1.1,1))
Warning: Removed 1 rows containing missing values (`geom_text()`).

Will limit analyses to samples with CT<26, where we are more confident in reproducibility of minor variant

samples_n_var %>% filter(INSTRUMENT_RESULT<26 & n_var < 30) %>% pull(n_var) %>% quantile(c(0.5,0.7))
50% 70% 
  5   7 
samples_to_analyze <- samples_n_var %>% filter(INSTRUMENT_RESULT<26) %>% pull(MCoVNumber)
lineages_figure <- mcov_samples_filtered %>% 
  filter(MCoVNumber %in% samples_to_analyze) %>% 
  mutate(variant=case_when(startsWith(scorpio_call,"Delta") ~ "Delta",
        startsWith(scorpio_call,"Alpha") ~ "Alpha",
        !(startsWith(scorpio_call,"Delta")|
            startsWith(scorpio_call,"Alpha")) ~ "other lineages")) %>%
  mutate(variant=if_else(lineage == "B.1.2","B.1.2",variant)) %>%
  ggplot(aes(x=COLLECTION_DT)) + geom_bar(aes(fill=variant)) + theme_bw() + 
  scale_fill_manual(values=c("#00A08A", "#F2AD00", "#F98400", "#5BBCD6")) + 
  xlab("Collection date") + ylab("No. samples") + 
  ggtitle(paste0('Final sample set, CT<26, n =',length(samples_to_analyze))) + 
  scale_x_date(minor_breaks="1 month")

#SUPP FIG 2
lineages_figure

samples_n_var %>% filter(INSTRUMENT_RESULT<26) %>% pull(n_var) %>% summary()
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   0.00    2.00    5.00   10.79   10.00  379.00 
#plot_grid(coverage_pre_filtering, ct_inclusion, ncol=2, labels=c("a","b"))
minor_sites_lowct<-minor_variant_sites_threshold %>% left_join(mcov_samples_filtered) %>% 
  filter(INSTRUMENT_RESULT<26) 
Joining, by = "MCoVNumber"

What kinds of run-specific effects do we see even after filtering for high-quality samples?

((n_var_by_run <- samples_n_var %>% filter(INSTRUMENT_RESULT < 26 & n_var < 30) %>% 
    ggplot(aes(x=run, y=n_var)) + geom_boxplot() + theme_bw() + 
    theme(axis.text.x = element_text(angle = 90)) + xlab("Run") + ylab("No. minor variants")))

#are run effects related to sequencing depth?
n_var_by_coverage<-samples_n_var %>% filter(INSTRUMENT_RESULT<26) %>% ggplot(aes(x=median_coverage, y=n_var)) + geom_point(alpha=0.5) + geom_smooth() + theme_bw() + xlab("Sample median coverage") + ylab("No. minor variants in sample")
#not on the individual sample level
#is average minor variant richness in a run related to average depth of coverage in the run?
n_var_depth_averages<-samples_n_var %>% filter(INSTRUMENT_RESULT<26) %>% group_by(run) %>% summarise(median_n_var=median(n_var), median_sample_coverage=median(median_coverage), median_ct=median(INSTRUMENT_RESULT)) %>% ggplot(aes(x=median_sample_coverage, y=median_n_var)) + geom_point() + theme_bw() + xlab("Run-level median of median coverage") + ylab("Median no. minor variants of samples in run") + geom_smooth(method=lm) 
samples_n_var %>% filter(INSTRUMENT_RESULT<26) %>% filter(run=="Run_90") %>% ggplot(aes(x=median_coverage, y=n_var)) + geom_point() + ggtitle("Run 90 - very high average coverage") + theme_bw() + geom_hline(yintercept=10, linetype="dotted")

samples_n_var %>% filter(INSTRUMENT_RESULT<26) %>% filter(run=="Run_29") %>% ggplot(aes(x=median_coverage, y=n_var)) + geom_point() + ggtitle("Run 29 - lower average coverage") + theme_bw() + geom_hline(yintercept=10, linetype="dotted")

#are the run-specific differences in coverage stronger in samples that were included or that weren't included?
mcov_samples %>% mutate(hq_sample=if_else(MCoVNumber %in% minor_sites_lowct$MCoVNumber, "hq","excluded")) %>%  ggplot(aes(x=run, y=median_coverage)) + geom_boxplot() +theme_bw() + theme(axis.text.x=element_text(angle=90)) + facet_grid(hq_sample~.) 

#SUPP FIG 3
plot_grid(n_var_by_run, plot_grid(n_var_by_coverage, n_var_depth_averages, nrow=2), ncol=2, rel_widths = c(2,1), labels=c("a","b"))
`geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'`geom_smooth()` using formula = 'y ~ x'

LS0tCnRpdGxlOiAiUiBOb3RlYm9vayIKb3V0cHV0OgogIGh0bWxfbm90ZWJvb2s6IGRlZmF1bHQKICBodG1sX2RvY3VtZW50OgogICAgZGZfcHJpbnQ6IHBhZ2VkCiAgcGRmX2RvY3VtZW50OiBkZWZhdWx0Ci0tLQoKIyBXaXRoaW4taG9zdCBkaXZlcnNpdHkgYW5kIG1pbm9yIHZhcmlhbnQgYW5hbHlzZXMgaW4gc2FtcGxlcyBmcm9tIEhvdXN0b24gTWV0aG9kaXN0IEhvc3BpdGFsLCAyMDIxCgojIyBTYW1wbGUgY2hhcmFjdGVyaXN0aWNzIGFuZCBpbmNsdXNpb24gY3JpdGVyaWEgCgpgYGB7cn0KCiMjIyMjIExvYWQgbGlicmFyaWVzIGFuZCBkZWZpbmUgcmVjdXJyaW5nIGZ1bmN0aW9ucyAvIHZhcmlhYmxlcwpzb3VyY2UoIi4vc2NyaXB0cy9zdGFydHVwLlIiKQoKI2FsbCBtY292IHNhbXBsZXMgd2UgaGF2ZSBldmVyIHJlY2VpdmVkIC0gcmVmb3JtYXQgc2FtcGxlIG5hbWVzIHRvIGJlIGNvbnNpc3RlbnQKbWNvdl9zYW1wbGVzX2FsbCA8LSBmcmVhZCgiZnVsbF9saW5lYWdlX3JlcG9ydF8yMDIyMDUwNy50c3YiLCBkYXRhLnRhYmxlPUYpICU+JSAKICBtdXRhdGUoTUNvVk51bWJlcj1tY292X3JlZm9ybWF0KHRheG9uKSkgJT4lIAogIGZpbHRlcihzdGFydHNXaXRoKE1Db1ZOdW1iZXIsICJNQ29WIikpICU+JSAKICBmaWx0ZXIoTUNvVk51bWJlciE9Ik1Db1YzMDkwNCIpICNyZW1vdmUgb25lIHNhbXBsZSB3aXRoIGluY29uc2lzdGVudGx5IGZvcm1hdHRlZCBkdXBsaWNhdGVzCgojcnVuIGFuZCBkYXRlIGluZm87IGtlZXAgb25seSBlYXJsaWVzdCBzYW1wbGUgZnJvbSB0aGUgc2FtZSBwYXRpZW50Cm1jb3ZfaW5mbyA8LSBmcmVhZCgic2FtcGxlX2RhdGVfYW5kX3J1bi5jc3YiLCBkYXRhLnRhYmxlPUYpICU+JSAKICBtdXRhdGUoQ09MTEVDVElPTl9EVD1hcy5EYXRlKENPTExFQ1RJT05fRFQsICIlbS8lZC8leSIpLCAKICAgICAgICAgTUNvVk51bWJlcj1zdHJfcmVtb3ZlKG1jb3ZfaWQsICItIikpICU+JSAKICBhcnJhbmdlKENPTExFQ1RJT05fRFQpICU+JSBmaWx0ZXIoIWR1cGxpY2F0ZWQoUGF0aWVudElEKSkKCiNzYW1wbGVzIHdlIHJlY2VpdmVkIHRoYXQgd2UncmUgaW50ZXJlc3RlZCBpbiAoRGVjZW1iZXIgMjAyMC1Ob3ZlbWJlciAyMDIxKQptY292X3NhbXBsZXNfMSA8LSBtY292X3NhbXBsZXNfYWxsICU+JSBmaWx0ZXIoIXRheG9uICVpbiUgZHVwNjUuNjYpICU+JSAKICBmaWx0ZXIoTUNvVk51bWJlciAlaW4lIG1jb3ZfaW5mbyRNQ29WTnVtYmVyKSAlPiUgbGVmdF9qb2luKG1jb3ZfaW5mbykKCiNhbGwgc2FtcGxlcyBzZXF1ZW5jZWQgaW4gZWFjaCBydW4gKGluY2x1ZGluZyB0aG9zZSBmcm9tIG91dHNpZGUgb2YgdGhpcyBzdHVkeSBwZXJpb2QpIC0tIHNvbWV0aW1lcyByZWxldmFudCBmb3IgcnVuIFFDIHB1cnBvc2VzCnJ1bnNfYWxsX3NhbXBsZXMgPC0gZnJlYWQoInJ1bl9zYW1wbGVzLmNzdiIsIGRhdGEudGFibGUgPSBGKSAlPiUgCiAgbXV0YXRlKE1Db1ZOdW1iZXI9c3RyX3JlbW92ZShgU2FtcGxlIElEYCwiLSIpLCBydW49UnVuKSAlPiUgCiAgc2VsZWN0KHJ1biwgTUNvVk51bWJlcikKCiNzdW1tYXJ5IHN0YXRzIG9uIGNvdmVyYWdlIG9mIGVhY2ggc2FtcGxlOyBkcm9wIHRoZSBydW4gNjUgZHVwbGljYXRlcyBhbmQgam9pbiBjb3ZlcmFnZSBpbmZvIHRvIG1haW4gZGF0YXNldApkMSA9IGZyZWFkKCdjb3ZlcmFnZV9sZXZlbHNfMjAyMjA1MDcuY3N2JywgZGF0YS50YWJsZSA9IEYpICU+JSAKICBmaWx0ZXIoZHVwbGljYXRlZChzYW1wbGVuYW1lKSkgJT4lIHB1bGwoc2FtcGxlbmFtZSkKZDIgPSBmcmVhZCgnY292ZXJhZ2VfbGV2ZWxzXzIwMjIwNTA3LmNzdicsIGRhdGEudGFibGUgPSBGKSAlPiUgCiAgZmlsdGVyKHNhbXBsZW5hbWUgJWluJSBkMSkgJT4lIGZpbHRlcighZHVwbGljYXRlZChzYW1wbGVuYW1lKSkgJT4lIAogIHB1bGwoZmlsZW5hbWUpCmNvdmVyYWdlX2xldmVscyA8LSBmcmVhZCgnY292ZXJhZ2VfbGV2ZWxzXzIwMjIwNTA3LmNzdicsIGRhdGEudGFibGUgPSBGKSAlPiUgCiAgZmlsdGVyKCFmaWxlbmFtZSAlaW4lIGQyKSAlPiUgZmlsdGVyKHNhbXBsZW5hbWUhPSJNQ29WMzA5MDQiKSAlPiUgc2VsZWN0KC0xKQpgYGAKCmBgYHtyfQojIGpvaW4gZGF0YWZyYW1lcwptY292X3NhbXBsZXM8LW1jb3Zfc2FtcGxlc18xICU+JSAKICBzZWxlY3QoTUNvVk51bWJlciwgbGluZWFnZSwgc2NvcnBpb19jYWxsLCBxY19zdGF0dXMsIAogICAgICAgICBDT0xMRUNUSU9OX0RULCBJTlNUUlVNRU5ULCBJTlNUUlVNRU5UX1JFU1VMVCwgcnVuPXJ1bl9ncm91cCkgJT4lIAogIGxlZnRfam9pbihjb3ZlcmFnZV9sZXZlbHMsIGJ5PWMoIk1Db1ZOdW1iZXIiPSJzYW1wbGVuYW1lIikpCgptY292X3NhbXBsZXNfd2l0aF9jdDwtbWNvdl9zYW1wbGVzICU+JSBmaWx0ZXIoSU5TVFJVTUVOVF9SRVNVTFQ8NTApICU+JSAKICBtdXRhdGUoQ1Q9SU5TVFJVTUVOVF9SRVNVTFQpCiN3aGF0J3MgdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIENUIHZhbHVlIGFuZCByZWFkIGNvdmVyYWdlPwpjb3ZlcmFnZV9hbGw8LW1jb3Zfc2FtcGxlc193aXRoX2N0ICU+JSBnZ3Bsb3QoYWVzKHg9Q1QsIHk9bWVkaWFuX2NvdmVyYWdlKSkgKyAKICBnZW9tX3BvaW50KGFscGhhPTAuMDcpICsgdGhlbWVfYncoKSArIHhsYWIoIkN0IHZhbHVlIikgKyB5bGFiKCJTYW1wbGUgbWVkaWFuIGRlcHRoIikKI2hvdyBkb2VzIGNvdmVyYWdlIGluIGhpZ2gtQ1Qgc2FtcGxlcyBjb21wYXJlIHdpdGggdGhlIHJlc3Qgb2YgdGhlbT8KY292ZXJhZ2VfY3RfY2F0PC1tY292X3NhbXBsZXNfd2l0aF9jdCAlPiUgbXV0YXRlKHNhbXBsZV9jdD1pZl9lbHNlKENUPj00MCwgIkNUPj00MCIsICJDVDw0MCIpKSAlPiUgCiAgZ2dwbG90KGFlcyh4PXNhbXBsZV9jdCwgeT1tZWRpYW5fY292ZXJhZ2UpKSArIAogIGdlb21fcG9pbnQoYWxwaGE9MC4yLCBwb3NpdGlvbj1wb3NpdGlvbl9qaXR0ZXIod2lkdGg9MC4yNSkpICsgCiAgZ2VvbV9ib3hwbG90KGNvbG9yPSJyZWQiLCBhbHBoYT0wKSArIHRoZW1lX2J3KCkgKyAKICB4bGFiKCJDdCB2YWx1ZSIpICsgeWxhYigiU2FtcGxlIG1lZGlhbiBkZXB0aCIpCiNzZWUgdGhhdCBDVD49NDAgc2FtcGxlcyB0ZW5kIHRvIGhhdmUgZXh0cmVtZWx5IGxvdyBjb3ZlcmFnZSwgYnV0IHNvbWUgb3V0bGllcnMKI1NVUFAgRklHIDEyCiNjb3ZlcmFnZV9wcmVfZmlsdGVyaW5nPC1wbG90X2dyaWQoY292ZXJhZ2VfYWxsLCBjb3ZlcmFnZV9jdF9jYXQpCiNjb3ZlcmFnZV9wcmVfZmlsdGVyaW5nCmBgYAoKCgojIyBSdW4tbGV2ZWwgUUMgCgpgYGB7cn0KI2FyZSB0aGVyZSBhbnkgcnVucyB3aGVyZSBoaWdoLUNUIHNhbXBsZXMgaGF2ZSB1bnVzdWFsbHkgaGlnaCBjb3ZlcmFnZT8gdHJlYXQgQ1Q+NDAgc2FtcGxlcyBhcyBuZWdhdGl2ZSBjb250cm9scyBhbmQgZWxpbWluYXRlIHJ1bnMgd2hlcmUgdGhlaXIgY292ZXJhZ2UgaXMgbm90IGRpZmZlcmVudCBmcm9tIHRob3NlIG9mIHRoZSByZXN0IG9mIHRoZSBzYW1wbGVzCnRlc3RfZ3JvdXA8LW1jb3Zfc2FtcGxlc193aXRoX2N0ICU+JSBtdXRhdGUoaXNfbmVnPWlmX2Vsc2UoQ1Q+PTQwLDEsMCkpICU+JSAKICBncm91cF9ieShydW4pICU+JSBtdXRhdGUobl9uZWdzPXN1bShpc19uZWcpKSAlPiUgZmlsdGVyKG5fbmVncz49MykgJT4lIAogIHVuZ3JvdXAoKSAlPiUgbXV0YXRlKHNhbXBsZXR5cGU9aWZfZWxzZShpc19uZWc9PTEsICJuZWdjdHJsIiwic2FtcGxlIikpCnJ1bnNfdG9fZHJvcDEgPSB0ZXN0X2dyb3VwICU+JSBncm91cF9ieShydW4pICU+JSAKICBzdW1tYXJpc2UodF90ZXN0X3A9dC50ZXN0KGZyYWN0aW9uXzEwMDB4X2NvdmVyYWdlfnNhbXBsZXR5cGUpJHAudmFsdWUpICU+JSAKICBhcnJhbmdlKGRlc2ModF90ZXN0X3ApKSAlPiUgZmlsdGVyKHRfdGVzdF9wPjAuMDEpICU+JSBwdWxsKHJ1bikKcnVuc190b19kcm9wMiA9IHRlc3RfZ3JvdXAgJT4lIGdyb3VwX2J5KHJ1bikgJT4lIAogIHN1bW1hcmlzZSh0X3Rlc3RfcD10LnRlc3QobWVkaWFuX2NvdmVyYWdlfnNhbXBsZXR5cGUpJHAudmFsdWUpICU+JSAKICBhcnJhbmdlKGRlc2ModF90ZXN0X3ApKSAlPiUgZmlsdGVyKHRfdGVzdF9wPjAuMDEpICU+JSBwdWxsKHJ1bikKCiMjIyMjIyMjIyMjIyAKcnVuc190b19kcm9wPC11bmlvbihydW5zX3RvX2Ryb3AxLCBydW5zX3RvX2Ryb3AyKQoKbWNvdl9zYW1wbGVzX3dpdGhfY3QgJT4lIHB1bGwocnVuKSAlPiUgdW5pcXVlKCkKdGVzdF9ncm91cCAlPiUgZ3JvdXBfYnkocnVuLCBzYW1wbGV0eXBlKSAlPiUgc3VtbWFyaXplKGNvdW50cyA9IG4oKSkgJT4lIAogIGZpbHRlcihydW4gJWluJSBydW5zX3RvX2Ryb3ApICU+JSBucm93KCkKCm1jb3Zfc2FtcGxlc193aXRoX2N0ICU+JSBwdWxsKHJ1bikgJT4lIHVuaXF1ZSgpCnRlc3RfZ3JvdXAgJT4lIGdyb3VwX2J5KHJ1biwgc2FtcGxldHlwZSkgJT4lIHN1bW1hcml6ZShjb3VudHMgPSBuKCkpICU+JSAKICBmaWx0ZXIoc2FtcGxldHlwZT09Im5lZ2N0cmwiKSAlPiUgYXJyYW5nZShjb3VudHMpICU+JSBtdXRhdGUoZHJvcHBlZCA9IHJ1biAlaW4lIHJ1bnNfdG9fZHJvcCkgJT4lCiAgZ2dwbG90KGFlcyhkcm9wcGVkLGNvdW50cywgbGFiZWw9cnVuKSkgKyBnZW9tX2JveHBsb3QoKSArIGdlb21fcG9pbnQoKSArIGdlb21fdGV4dF9yZXBlbCgpICsgdGhlbWVfcHVicigpCgpydW5zX2tlcHQgPSBtY292X3NhbXBsZXNfd2l0aF9jdCRydW5bIW1jb3Zfc2FtcGxlc193aXRoX2N0JHJ1biAlaW4lIHJ1bnNfdG9fZHJvcF0gJT4lIHVuaXF1ZSgpCiMgZm9yIChpIGluIHJ1bnNfa2VwdCkgewojICAgZiA9IG1jb3Zfc2FtcGxlc193aXRoX2N0ICU+JSBmaWx0ZXIocnVuID09IGkpICU+JSBnZ3Bsb3QoYWVzKElOU1RSVU1FTlRfUkVTVUxULCBmcmFjdGlvbl8xMDAweF9jb3ZlcmFnZSkpICsgZ2VvbV9wb2ludCgpICsgZ2d0aXRsZShpKSArIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDQwLCBmYWNlID0gImJvbGQiKSkKIyAgIHByaW50KGYpCiMgfQpgYGAKCmBgYHtyfQpmMSA9IG1jb3Zfc2FtcGxlc193aXRoX2N0ICU+JSBnZ3Bsb3QoYWVzKElOU1RSVU1FTlRfUkVTVUxULCBmcmFjdGlvbl8xMDAweF9jb3ZlcmFnZSkpICsgCiAgZ2VvbV9wb2ludChzaGFwZT0iLiIsIGFscGhhID0gMC41KSArIHRoZW1lX3B1YnIoKSArIAogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IDQwLCBmYWNlID0gImJvbGQiKSkgKyAKICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQ9NDAsIGNvbG9yID0gInJlZCIpCmYxID0gZ2dNYXJnaW5hbChmMSArIHJyZW1vdmUoInhsYWIiKSkKCmYyID0gbWNvdl9zYW1wbGVzX3dpdGhfY3QgJT4lIGdncGxvdChhZXMoSU5TVFJVTUVOVF9SRVNVTFQsIGxvZzEwKG1lZGlhbl9jb3ZlcmFnZSkpKSArIAogIGdlb21fcG9pbnQoc2hhcGU9Ii4iLCBhbHBoYSA9IDAuNSkgKyB0aGVtZV9wdWJyKCkgKyAKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSA0MCwgZmFjZSA9ICJib2xkIikpICsgCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0PTQwLCBjb2xvciA9ICJyZWQiKQpmMiA9IGdnTWFyZ2luYWwoZjIpCgpnZ2FycmFuZ2UoZjEsIGYyLCBuY29sID0gMSwgbnJvdyA9IDIsIGFsaWduID0gInYiKQpgYGAKCmBgYCB7cn0KIyB0bXAgPSBkYXRhLnRhYmxlKG1jb3Zfc2FtcGxlc193aXRoX2N0ICU+JSBmaWx0ZXIoQ1Q+MzUpKVsgLCBpbnZpc2libGUoY29yLnRlc3QoZnJhY3Rpb25fMTAwMHhfY292ZXJhZ2UsIC1DVCwgbWV0aG9kPSJzcGVhcm1hbiIpWy0yXSksIGJ5PXJ1bl0gJT4lIHNlbGVjdChydW4sIHAudmFsdWUsIGVzdGltYXRlKSAlPiUKIyAgIG11dGF0ZTsgdG1wCiMgdG1wID0gdG1wICU+JSBtdXRhdGUoYWJub3JtYWwgPSBydW4gJWluJSAgIAojICAgICAgICBjKCJSdW5fMjAiLCJSdW5fODkiLCJSdW5fMjEiLCJSdW5fNTgiLCJSdW5fNzYiLCJSdW5fNzEiLCJSdW5fNzUiLAojICAgICAgICAiUnVuXzg2IiwiUnVuXzc0IiwiUnVuXzcwIiwiUnVuXzc4IiwiUnVuXzYyIiwiUnVuXzEzIiwiUnVuXzg1IiwKIyAgICAgICAgIlJ1bl82NSIsIlJ1bl8zNCIsIlJ1bl84NyIsIlJ1bl8xMSIsIlJ1bl84MyIsIlJ1bl8xNiIsIlJ1bl83NyIsCiMgICAgICAgICJSdW5fODEiKSkKIyBnZ3Bsb3QodG1wLCBhZXMoZXN0aW1hdGUsIC1sb2cxMChwLnZhbHVlKSwgY29sb3IgPSBhYm5vcm1hbCwgCiMgICAgICAgICAgICAgICAgIGxhYmVsID0gZ3N1YigiUnVuXyIsICIiLCBydW4pKSkgKyAKIyAgICAgICAgICBnZW9tX3BvaW50KCkgKyBnZW9tX3RleHRfcmVwZWwoKSsgdGhlbWVfcHVicigpCiMgCiMgdG1wICU+JSBhcnJhbmdlKC1wLnZhbHVlKQojICMgcnVucyAyCmBgYAoKYGBge3J9CiMjIyBwbG90IGJveHBsb3Qgb2YgdGhlIHJ1bnMKc3RtcCA9IG1jb3Zfc2FtcGxlc193aXRoX2N0ICU+JSBtdXRhdGUoYWJub3JtYWwgPSBydW4gJWluJSAgIAogICAgcnVuc190b19kcm9wKSAlPiUgbXV0YXRlKHJ1biA9IGdzdWIoIlJ1bl8iLCAiIiwgcnVuKSkgJT4lIAogICAgbXV0YXRlKGlzX25lZz1pZl9lbHNlKENUPj00MCwxLDApKQoKZjMgPSBnZ3Bsb3Qoc3RtcCwgYWVzKHJ1biwgZnJhY3Rpb25fMTAwMHhfY292ZXJhZ2UsIGNvbG9yID0gYWJub3JtYWwsIGZpbGwgPSBhYm5vcm1hbCkpICsgCiAgZ2VvbV9ib3hwbG90KCkgKyAKICBnZW9tX3BvaW50KGRhdGEgPSBzdG1wICU+JSBmaWx0ZXIoaXNfbmVnID09IFQpLCAKICAgICAgICAgICAgIGFlcyhydW4sIGZyYWN0aW9uXzEwMDB4X2NvdmVyYWdlKSwgY29sb3IgPSAicmVkIiwgYWxwaGEgPSAuOSwgCiAgICAgICAgICAgICBzaGFwZSA9IDEpICsgCiAgc2NhbGVfZmlsbF9ncmV5KHN0YXJ0ID0gMSwgZW5kID0gMC44KSArIAogIHNjYWxlX2NvbG9yX2dyZXkoc3RhcnQ9MCwgZW5kPTAuNikgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTAsIGhqdXN0ID0gMSksIAogICAgICAgIHRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT04KSkgKwogIGxhYnMoIHggPSBOVUxMKQogIApmNCA9IGdncGxvdChzdG1wLCBhZXMocnVuLCBsb2cxMChtZWRpYW5fY292ZXJhZ2UpLCAKICAgICAgICAgICAgICAgICAgICAgIGNvbG9yID0gYWJub3JtYWwsIGZpbGwgPSBhYm5vcm1hbCkpICsgCiAgZ2VvbV9ib3hwbG90KCkgKyAKICBnZW9tX3BvaW50KGRhdGEgPSBzdG1wICU+JSBmaWx0ZXIoaXNfbmVnID09IFQpLCAKICAgICAgICAgICAgIGFlcyhydW4sIGxvZzEwKG1lZGlhbl9jb3ZlcmFnZSkpLCBjb2xvciA9ICJyZWQiLCBhbHBoYSA9IC45LCAKICAgICAgICAgICAgIHNoYXBlID0gMSkgKyAKICBzY2FsZV9maWxsX2dyZXkoc3RhcnQgPSAxLCBlbmQgPSAwLjgpICsgCiAgc2NhbGVfY29sb3JfZ3JleShzdGFydD0wLCBlbmQ9MC42KSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCwgaGp1c3QgPSAxKSwgCiAgICAgICAgdGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTgpKQogIApnZ2FycmFuZ2UoZjMsIGY0LCBuY29sID0gMSwgbnJvdyA9IDIsIGFsaWduID0gInYiLCBjb21tb24ubGVnZW5kID0gVCkKCmBgYAoKIyMgU2FtcGxlLWxldmVsIFFDCmBgYHtyfQojbmV4dGNsYWRlIFFDCm5jPC1mcmVhZCgiaG91c3Rvbl9uZXh0Y2xhZGUudHN2Iiwgc2VwPSdcdCcsIGRhdGEudGFibGUgPSBGKSAlPiUgCiAgbXV0YXRlKE1Db1ZOdW1iZXI9cmVnbWF0Y2hlcyhzZXFOYW1lLCByZWdleHByKCJbTSxSLFMsT11Db1YuWzAtOV0rIiwgc2VxTmFtZSkpICU+JSAKICAgICAgICAgICBzdHJfcmVtb3ZlKCItIikgJT4lIHN0cl9yZW1vdmUoIl8iKSkgJT4lIGZpbHRlcighZHVwbGljYXRlZChNQ29WTnVtYmVyKSkKbmV4dGNsYWRlX2JhZF9zYW1wbGVzPC1uYyAlPiUgZmlsdGVyKHFjLm92ZXJhbGxTdGF0dXMgJWluJSBjKCJiYWQiKSkgJT4lIHB1bGwoTUNvVk51bWJlcikKI2Ryb3AgYmFkIHJ1bnMgYW5kIHNhbXBsZXMgdGhhdCBkb24ndCBwYXNzIHBhbmdvbGluIFFDIG9yIG5leHRjbGFkZSBRQwptY292X3NhbXBsZXNfZmlsdGVyZWQ8LW1jb3Zfc2FtcGxlcyAlPiUgZmlsdGVyKCFydW4gJWluJSBydW5zX3RvX2Ryb3ApICU+JSAKICBmaWx0ZXIocWNfc3RhdHVzPT0icGFzcyIpICU+JSBmaWx0ZXIoIU1Db1ZOdW1iZXIgJWluJSBuZXh0Y2xhZGVfYmFkX3NhbXBsZXMpICU+JSAKICBmaWx0ZXIoc2NvcnBpb19jYWxsIT0iT21pY3JvbiAoQkEuMS1saWtlKSIpICU+JSAKICMjIyMjICNtYWluIGNvdmVyYWdlIGNyaXRlcmlvbiBmb3IgZmFpciBjb21wYXJpc29uczogWCBkZXB0aCBvdmVyIFkgcGVyY2VudCBvZiB0aGUgZ2Vub21lCiAgZmlsdGVyKGZyYWN0aW9uXzEwMHhfY292ZXJhZ2U+PTAuOTgpICU+JSBkcm9wbGV2ZWxzKCkKCiN3aGF0J3MgdGhlIGRpc3RyaWJ1dGlvbiBvZiBDVCB2YWx1ZXM/CmN0X2Rpc3RyaWJ1dGlvbl9hZnRlcl9xYzwtbWNvdl9zYW1wbGVzX2ZpbHRlcmVkICU+JSBmaWx0ZXIoSU5TVFJVTUVOVF9SRVNVTFQ8NTApICU+JSAKICBnZ3Bsb3QoYWVzKHg9SU5TVFJVTUVOVF9SRVNVTFQpKSArIGdlb21faGlzdG9ncmFtKGJpbndpZHRoPTEpICsgdGhlbWVfYncoKSArIAogIHhsYWIoIkN0IHZhbHVlIikgKyBsYWJzKGNhcHRpb249IkFmdGVyIGV4Y2x1c2lvbiBjcml0ZXJpYSIpCmBgYAoKYGBge3J9Cm5yb3cobWNvdl9zYW1wbGVzX2ZpbHRlcmVkICU+JSBmaWx0ZXIoSU5TVFJVTUVOVF9SRVNVTFQgPCAyNikpCmBgYAoKYGBge3J9CiNIb3cgZGlkIGV4Y2x1c2lvbiBjcml0ZXJpYSBjaGFuZ2UgZGlzdHJpYnV0aW9uIG9mIHNhbXBsZSBDdCB2YWx1ZXM/CgpjdF9kaXN0cmlidXRpb25fYWZ0ZXJfcWM8LW1jb3Zfc2FtcGxlc19maWx0ZXJlZCAlPiUgZmlsdGVyKElOU1RSVU1FTlRfUkVTVUxUPDUwKSAlPiUgZ2dwbG90KGFlcyh4PUlOU1RSVU1FTlRfUkVTVUxUKSkgKyBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aD0xKSArIHRoZW1lX2J3KCkgKyB4bGFiKCJDdCB2YWx1ZSIpCgpjdF9kaXN0cmlidXRpb25fYmVmb3JlX3FjPC1tY292X3NhbXBsZXMgJT4lIGZpbHRlcihJTlNUUlVNRU5UX1JFU1VMVDw1MCkgJT4lIGdncGxvdChhZXMoeD1JTlNUUlVNRU5UX1JFU1VMVCkpICsgZ2VvbV9oaXN0b2dyYW0oYmlud2lkdGg9MSkgKyB0aGVtZV9idygpICsgeGxhYigiQ3QgdmFsdWUiKSArIGxhYnMoY2FwdGlvbj0iQmVmb3JlIGV4Y2x1c2lvbiBjcml0ZXJpYSIpCiNjdF9pbmNsdXNpb248LXBsb3RfZ3JpZChjdF9kaXN0cmlidXRpb25fYmVmb3JlX3FjLCBjdF9kaXN0cmlidXRpb25fYWZ0ZXJfcWMsIG5yb3c9MikKCiNjdF9pbmNsdXNpb24KCgpjdF9kaXN0cmlidXRpb25fYWZ0ZXJfcWM8LW1jb3Zfc2FtcGxlc19maWx0ZXJlZCAlPiUgZmlsdGVyKElOU1RSVU1FTlRfUkVTVUxUPDUwKQoKY3RfZGlzdHJpYnV0aW9uX2JlZm9yZV9xYzwtbWNvdl9zYW1wbGVzICU+JSBmaWx0ZXIoSU5TVFJVTUVOVF9SRVNVTFQ8NTApCgpwbG90MV9jdF9iZWZvcmVfYWZ0ZXIgPSBnZ3Bsb3QoYWVzKHg9SU5TVFJVTUVOVF9SRVNVTFQpLCBkYXRhID0gY3RfZGlzdHJpYnV0aW9uX2JlZm9yZV9xYykgKyAKICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDEsIGZpbGwgPSAiZ3JleSIpICsKICBnZW9tX2hpc3RvZ3JhbShkYXRhID0gY3RfZGlzdHJpYnV0aW9uX2FmdGVyX3FjLCBiaW53aWR0aD0xKSArIHRoZW1lX3B1YnIoKSArIAogIHhsYWIoIkN0IHZhbHVlIikgKyB5bGFiKCIjIHNhbXBsZXMiKSAjKyBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSAyNiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjICAgICBsaW5ldHlwZSA9ICJkYXNoZWQiKQoKZ2dzYXZlKCJnZ3NhdmUvcGxvdDFfY3RfYmVmb3JlX2FmdGVyLnBkZiIsIHBsb3QxX2N0X2JlZm9yZV9hZnRlciwgaGVpZ2h0ID0gMiwgd2lkdGggPSA0KQpgYGAKCiMjIFByZWxpbWluYXJ5IG1pbm9yIHZhcmlhbnQgZGlzdHJpYnV0aW9ucwoKYGBge3J9CiNudWNsZW90aWRlIHBvc2l0aW9ucyBvZiBhbGwgcHJpbWVycyB1c2VkIGluIGRhdGFzZXQ7IHdpbGwgZXhjbHVkZSAKcHJpbWVycyA9IGZyZWFkKCJuQ29WLTIwMTkuYXJ0aWNfdjMucHJpbWVyLnR4dCIsIHNlcD0iXHQiLCBoZWFkZXI9RkFMU0UsIGRhdGEudGFibGU9RikgJT4lIAogIHNlbGVjdChzdGFydCA9IFYyLCBlbmQgPSBWMykKcHJpbWVyX3Bvc2l0aW9uc192MzwtYXMubnVtZXJpYygpCmZvciAoaSBpbiAxOm5yb3cocHJpbWVycykpewogIHByaW1lcl9wb3NpdGlvbnNfdjM8LWMocHJpbWVyX3Bvc2l0aW9uc192MywgcHJpbWVyc1tpLF0kc3RhcnQ6cHJpbWVyc1tpLF0kZW5kKQp9CgpwcmltZXJzID0gZnJlYWQoIm5Db1YtMjAxOS5hcnRpY192NC5wcmltZXIuYmVkIiwgc2VwPSJcdCIsIAogICAgICAgICAgICAgICAgaGVhZGVyPUZBTFNFLCBkYXRhLnRhYmxlID0gRikgJT4lIHNlbGVjdChzdGFydCA9IFYyLCBlbmQgPSBWMykKcHJpbWVyX3Bvc2l0aW9uc192NDwtYXMubnVtZXJpYygpCmZvciAoaSBpbiAxOm5yb3cocHJpbWVycykpewogIHByaW1lcl9wb3NpdGlvbnNfdjQ8LWMocHJpbWVyX3Bvc2l0aW9uc192NCwgcHJpbWVyc1tpLF0kc3RhcnQ6cHJpbWVyc1tpLF0kZW5kKQp9CgpwcmltZXJzID0gZnJlYWQoIlY0LjEuYmVkIiwgc2VwPSJcdCIsIGhlYWRlcj1GQUxTRSwgZGF0YS50YWJsZT1GKSAlPiUgCiAgc2VsZWN0KHN0YXJ0ID0gVjIsIGVuZCA9IFYzKQpwcmltZXJfcG9zaXRpb25zX3Y0LjEgPC0gYXMubnVtZXJpYygpCmZvciAoaSBpbiAxOm5yb3cocHJpbWVycykpewogIHByaW1lcl9wb3NpdGlvbnNfdjQuMSA8LSBjKHByaW1lcl9wb3NpdGlvbnNfdjQuMSwgcHJpbWVyc1tpLF0kc3RhcnQ6cHJpbWVyc1tpLF0kZW5kKQp9CgpwcmltZXJfcG9zaXRpb25zX2FsbCA8LSBjKHByaW1lcl9wb3NpdGlvbnNfdjMsIHByaW1lcl9wb3NpdGlvbnNfdjQsIHByaW1lcl9wb3NpdGlvbnNfdjQuMSkgJT4lIHVuaXF1ZSgpCgojcmVmZXJlbmNlIGdlbm9tZSB3aXRoIG51Y2xlb3RpZGUgcG9zaXRpb25zIG9mIGdlbmVzCmdlbmVzIDwtIGZyZWFkKCJudHBvc19nZW5lX3VwZGF0ZS5jc3YiLCBkYXRhLnRhYmxlID0gRikKZ2VuZV9uYW1lcyA8LSBnZW5lcyAlPiUgcHVsbChnZW5lX2lkKSAlPiUgdW5pcXVlKCkKZ2VuZXMkZ2VuZV9pZCA8LSBmYWN0b3IoZ2VuZXMkZ2VuZV9pZCwgbGV2ZWxzID0gZ2VuZV9uYW1lcykKYGBgCgpgYGB7cn0KIyMjIFVwZGF0ZSB0aGlzIGlmIHlvdSBjaGFuZ2Ugc2FtcGxlIGluY2x1c2lvbiBjcml0ZXJpYQojbWlub3JfdmFyaWFudF9zaXRlc19hbGxMZXZlbHMgPC0gZnJlYWQoIm1pbm9yX3NpdGVzXzEwMHhfYWxsXzIwMjIwNTA3LmNzdiIsIGRhdGEudGFibGU9RikgJT4lIG11dGF0ZShNQ29WTnVtYmVyPXJlZ21hdGNoZXMobmFtZSwgI3JlZ2V4cHIoIltNLFIsUyxPXUNvVi5bMC05XSsiLCBuYW1lKSkgJT4lIHN0cl9yZW1vdmUoIi0iKSAlPiUgc3RyX3JlbW92ZSgiXyIpKSAlPiUgZmlsdGVyKE1Db1ZOdW1iZXIgJWluJSAjbWNvdl9zYW1wbGVzX2ZpbHRlcmVkJE1Db1ZOdW1iZXIpCiN3cml0ZS5jc3YobWlub3JfdmFyaWFudF9zaXRlc19hbGxMZXZlbHMsICJtaW5vcl9zaXRlc193b3JraW5nc2FtcGxlc18xMDAtOThtaW5pbXVtLmNzdiIsIHJvdy5uYW1lcz1GQUxTRSkKYGBgCgpgYGB7cn0KIyMjIFVwZGF0ZSB0aGlzIGlmIGNoYW5nZSB0aGUgdGhyZXNob2xkcyBmb3IgY291bnRpbmcgbWlub3IgdmFyaWFudHMKI2ZpbGUgd2FzIGFscmVhZHkgZmlsdGVyZWQgdG8gc2l0ZXMgd2l0aCBtaW5pbXVtIDEwMCByZWFkcyBkZXB0aCBhbmQgQSxDLFQsRyBtaW5vciB2YXJpYW50IHByZXNlbnQgYW5kIGJpbm9taWFsIHNpZ25pZmljYW5jZSBjaGVjayBwYXNzZWQuIEZ1cnRoZXIgZmlsdGVyaW5nOgojZGVwdGhfYXRfc2l0ZTwtMTAwCiNtaW5vcl9mcmVxdWVuY3k8LTAuMDEKI3RvdGFsX21pbm9yX3JlYWRzPC01MAojCiNtaW5vcl92YXJpYW50X3NpdGVzX3RocmVzaG9sZF9hcHBsaWVkPC1mcmVhZCgibWlub3Jfc2l0ZXNfd29ya2luZ3NhbXBsZXNfMTAwLTk4bWluaW11bS5jc3YiLCBkYXRhLnRhYmxlID0gRikgJT4lCiMgIGZpbHRlcih0b3RhbGNvdW50Pj1kZXB0aF9hdF9zaXRlKSAlPiUKIyAgZmlsdGVyKCFudHBvcyAlaW4lIDE6MjY1KSAlPiUgZmlsdGVyKCFudHBvcz4yOTY3NCkgJT4lICNkb24ndCBpbmNsdWRlIDUnIGFuZCAzJyBVVFIKIyAgZmlsdGVyKCFudHBvcyAlaW4lIHByaW1lcl9wb3NpdGlvbnNfYWxsKSAlPiUgI2Rvbid0IGluY2x1ZGUgcHJpbWVyIGJpbmRpbmcgc2l0ZXMKIyAgZmlsdGVyKG1ham9yICVpbiUgYygiQSIsIkMiLCJUIiwiRyIpKSAlPiUgI2Rvbid0IHdhbnQgbWlub3IgdmFyaWFudHMgYXQgY29uc2Vuc3VzIGRlbGV0aW9uIHNpdGVzCiMgIGZpbHRlcihtaW5vcmZyZXE+PW1pbm9yX2ZyZXF1ZW5jeSkgIyU+JQojICAjZmlsdGVyKG1pbm9yZnJlcSp0b3RhbGNvdW50Pj10b3RhbF9taW5vcl9yZWFkcykgCgojd3JpdGUuY3N2KG1pbm9yX3ZhcmlhbnRfc2l0ZXNfdGhyZXNob2xkX2FwcGxpZWQsICdtaW5vcl92YXJpYW50c19maWx0ZXJlZF8xMDB4MC4wMV81MC5jc3YnKQpgYGAKCmBgYHtyfQojbG9hZCBmaWxlIHRoYXQgd2FzIGdlbmVyYXRlZC9zYXZlZCBhYm92ZQptaW5vcl92YXJpYW50X3NpdGVzX3RocmVzaG9sZCA8LSBmcmVhZCgnbWlub3JfdmFyaWFudHNfZmlsdGVyZWRfMTAweDAuMDFfNTAuY3N2JywgZGF0YS50YWJsZT1GKSAKbWlub3JfdmFyaWFudF9zaXRlc190aHJlc2hvbGQgJT4lIHB1bGwoTUNvVk51bWJlcikgJT4lIHVuaXF1ZSAlPiUgbGVuZ3RoCmBgYAoKIyMgT3ZlcmFsbCBtaW5vciB2YXJpYW50IHJpY2huZXNzCgpgYGB7cn0Kbl92YXIgPC0gbWlub3JfdmFyaWFudF9zaXRlc190aHJlc2hvbGQgJT4lIGdyb3VwX2J5KE1Db1ZOdW1iZXIpICU+JSB0YWxseSgpICU+JSBhcnJhbmdlKGRlc2MobikpICN0aGlzIHRhbGx5IGRvZXNuJ3QgaW5jbHVkZSBhbnkgc2FtcGxlcyB3aXRoIDAgdmFyaWFudHMsIHNvIG5lZWQgdG8gam9pbiB0byBvcmlnaW5hbCBsaXN0CnNhbXBsZXNfbl92YXIgPC0gbWNvdl9zYW1wbGVzX2ZpbHRlcmVkICU+JSBsZWZ0X2pvaW4obl92YXIpICU+JSBhcnJhbmdlKENPTExFQ1RJT05fRFQpICU+JSBtdXRhdGUobl92YXI9dGlkeXI6OnJlcGxhY2VfbmEobiwwKSkgCgojd2hhdCdzIHRoZSBkaXN0cmlidXRpb24gb2YgbWlub3IgdmFyaWFudCByaWNobmVzcz8KIyMjIAooKAogIG5fdmFyX3NlbGVjdCA8LSBzYW1wbGVzX25fdmFyICU+JSBnZ3Bsb3QoYWVzKHg9bl92YXIpKSArIAogIGdlb21faGlzdG9ncmFtKGJpbndpZHRoPTUpICsgdGhlbWVfcHVicigpICsgCiAgeGxhYigiTm8uIG1pbm9yIHZhcmlhbnRzIGluIHNhbXBsZSIpICsgeWxhYigiTm8uIHNhbXBsZXMiKSArIAogIHNjYWxlX3lfY29udGludW91cyh0cmFucz0nbG9nMXAnLCBicmVha3M9YygxLCAxMCwgMTAwLCAxMDAwLCA1MDAwKSkKKSkKYGBgCgpgYGB7cn0KI3doYXQncyB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gbWlub3IgdmFyaWFudCByaWNobmVzcyBhbmQgQ3QgdmFsdWU/CiMgbl92YXJfc2VsZWN0X2N0PC1zYW1wbGVzX25fdmFyICU+JSBmaWx0ZXIoSU5TVFJVTUVOVF9SRVNVTFQ8NTApICU+JSAKIyAgIGdncGxvdChhZXMoeD1JTlNUUlVNRU5UX1JFU1VMVCwgeT1uX3ZhcikpICsgCiMgICBnZW9tX3BvaW50KGNvbG9yID0gImJsYWNrIiwgc2hhcGUgPSAxLCBhbHBoYSA9IDEvOCkgKyB0aGVtZV9wdWJyKCkgKyAKIyAgIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBzZXEoMCw0MCxieSA9IDUpKSArCiMgICB4bGFiKCJDdCB2YWx1ZSIpICsgeWxhYigiTm8uIG1pbm9yIHZhcmlhbnRzIikKIyBnZ01hcmdpbmFsKG5fdmFyX3NlbGVjdF9jdCkKCm5fdmFyX3NlbGVjdF9jdCA9IHNhbXBsZXNfbl92YXIgJT4lIGZpbHRlcihJTlNUUlVNRU5UX1JFU1VMVDw1MCkgJT4lIAogIGdncGxvdChhZXMoeD1JTlNUUlVNRU5UX1JFU1VMVCwgeT1uX3ZhcikpICsgCiAgZ2VvbV9wb2ludChzaGFwZSA9IDEsIGFscGhhID0gMS84KSArIAogIGdlb21fZGVuc2l0eV8yZChhbHBoYSA9IDEvMiwgY29sb3IgPSAicmVkIikgKyAKICBzY2FsZV95X2NvbnRpbnVvdXModHJhbnMgPSAibG9nMXAiLCBicmVha3MgPSBjKDAsMSw1LDEwLDMwLDUwLDEwMCwzMDAsNTAwKSkgKwogIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBzZXEoMCw0MCxieSA9IDUpKSArCiAgdGhlbWVfcHVicigpICsgeGxhYigiQ3QgdmFsdWUiKSArIHlsYWIoIm5fdmFyIikgKwogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDMwLCBsaW5ldHlwZSA9ICJkYXNoZWQiKSArIAogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDI2LCBsaW5ldHlwZSA9ICJkYXNoZWQiKQoKcGxvdDFfdGFyZ2V0ID0gZ2dNYXJnaW5hbChuX3Zhcl9zZWxlY3RfY3QsIHR5cGUgPSAidmlvbGluIiwgZHJhd19xdWFudGlsZXMgPSAKICAgICAgICAgICAgIGMoLjI1LC41LC43NSkpCgpnZ3NhdmUoImdnc2F2ZS9wbG90MV90YXJnZXQucGRmIiwgcGxvdCA9IHBsb3QxX3RhcmdldCwgaGVpZ2h0ID0gMywgd2lkdGggPSA0KQoKCiMgcGF0aWVudF9kYXRhPC1mcmVhZCgic2FtcGxlX2FuZF9wYXRpZW50X2RhdGEuY3N2IixkYXRhLnRhYmxlPUYpICAlPiUgbXV0YXRlKE1Db1ZOdW1iZXI9c3RyX3JlbW92ZShtY292X2lkLCAiLSIpKSAlPiUgc2VsZWN0KC1DT0xMRUNUSU9OX0RUKSAlPiUgaW5uZXJfam9pbihzYW1wbGVzX25fdmFyKQoKIyB0ZXN0X2N0ID0gcGF0aWVudF9kYXRhICU+JSBmaWx0ZXIoSU5TVFJVTUVOVF9SRVNVTFQ8NDApICU+JSBnZ3Bsb3QoYWVzKHg9SU5TVFJVTUVOVF9SRVNVTFQsIHk9bl92YXIsIGNvbG9yID0gYXMuZmFjdG9yKEFkbWl0dGVkX1lOKSkpICsgZ2VvbV9wb2ludChzaGFwZSA9IDEsIGFscGhhID0gMS84KSArIGdlb21fZGVuc2l0eV8yZChhbHBoYSA9IDEvMikgKyBzY2FsZV95X2NvbnRpbnVvdXModHJhbnMgPSAibG9nMiIsIGJyZWFrcyA9IGMoMCwxLDIsNCw4LDE2LDMyLDY0LCAxMjgsIDI1NikpKwojICAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IHNlcSgwLDQwLGJ5ID0gNSkpICsKIyAgIHRoZW1lX3B1YnIoKSArIHhsYWIoIkN0IHZhbHVlIikgKyB5bGFiKCIjIG1pbm9yIHZhcmlhbnRzIikgKyBnZW9tX3Ntb290aChtZXRob2Q9bG0pCiMgZ2dNYXJnaW5hbCh0ZXN0X2N0LCBncm91cENvbG91ciA9IFRSVUUsIGdyb3VwRmlsbCA9IFRSVUUsIHR5cGUgPSAidmlvbGluIiwgZHJhd19xdWFudGlsZXMgPSBjKC41KSkKCgojRklHVVJFIDFCCgojbl92YXJfY3Rfem9vbTwtbl92YXJfc2VsZWN0X2N0ICsgYW5ub3RhdGUoInJlY3QiLCB4bWluPTUsIHhtYXg9MjYsIHltaW49MCwgeW1heD1JbmYsIGFscGhhPTAuMiwgZmlsbD0iZ3JheSIpICsgdGhlbWVfcHVicgojbl92YXJfY3Rfem9vbQpgYGAKYGBge3J9CiMgdGVzdF9jdCA9IHBhdGllbnRfZGF0YSAlPiUgZmlsdGVyKElOU1RSVU1FTlRfUkVTVUxUPDQwKSAlPiUgbXV0YXRlKHZhY2NpbmUgPSBpZl9lbHNlKFZhY2NpbmVfU3RhdHVzPT0iTm8gdmFjY2luZSIsIDAsIDEpKSAlPiUgZ2dwbG90KGFlcyh4PUlOU1RSVU1FTlRfUkVTVUxULCB5PW5fdmFyLCBjb2xvciA9IGFzLmZhY3Rvcih2YWNjaW5lKSkpICsgZ2VvbV9wb2ludChzaGFwZSA9IDEsIGFscGhhID0gMS84KSArIGdlb21fZGVuc2l0eV8yZChhbHBoYSA9IDEvMikgKyBzY2FsZV95X2NvbnRpbnVvdXModHJhbnMgPSAibG9nMiIsIGJyZWFrcyA9IGMoMCwxLDIsNCw4LDE2LDMyLDY0LCAxMjgsIDI1NikpKwojICAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IHNlcSgwLDQwLGJ5ID0gNSkpICsKIyAgIHRoZW1lX3B1YnIoKSArIHhsYWIoIkN0IHZhbHVlIikgKyB5bGFiKCJOby4gbWlub3IgdmFyaWFudHMiKSArIGdlb21fc21vb3RoKG1ldGhvZD1sbSkKIyBnZ01hcmdpbmFsKHRlc3RfY3QsIGdyb3VwQ29sb3VyID0gVFJVRSwgZ3JvdXBGaWxsID0gVFJVRSwgdHlwZSA9ICJ2aW9saW4iLCBkcmF3X3F1YW50aWxlcyA9IGMoLjUpKQpgYGAKCmBgYHtyfQojIGdnZHJhdyhuX3Zhcl9zZWxlY3QgKyB0aGVtZV9oYWxmX29wZW4oMTIpKSArCiMgICAgZHJhd19wbG90KG5fdmFyX2N0X3pvb20sIHg9MC4zLCB5PTAuMywgd2lkdGg9MC43LCBoZWlnaHQ9MC43KSArCiMgICAgZHJhd19wbG90X2xhYmVsKAojICAgICAgYygiYSIsICJiIiksCiMgICAgICBjKDAsIDAuMyksCiMgICAgICBjKDEsIDEpLAojICAgICAgc2l6ZSA9IDEyCiMgICAgKQpgYGAKCmBgYHtyfQpzYW1wbGVzX25fdmFyICU+JSBwdWxsKG5fdmFyKSAlPiUgc3VtbWFyeSgpCmBgYAoKIyMgUmVwcm9kdWNpYmlsaXR5IG9mIG1pbm9yIHZhcmlhbnRzCgpgYGB7cn0KYWxsX3JlcGxpY2F0ZXNfdGFibGVfZmlsdCA8LSBmcmVhZCgicmVwbGljYXRlZF9zYW1wbGVzLmNzdiIsIGRhdGEudGFibGU9RikgJT4lIGZpbHRlcihNQ29WTnVtYmVyICVpbiUgc2FtcGxlc19uX3ZhciRNQ29WTnVtYmVyKQpgYGAKCmBgYHtyfQptaW5vcnNfdGFibGU8LWFsbF9yZXBsaWNhdGVzX3RhYmxlX2ZpbHQgJT4lIAogIGZpbHRlcihtYWpvci5vcmlnaW5hbCAlaW4lIGMoIkEiLCJDIiwiVCIsIkciKSkgJT4lIAogIGZpbHRlcihtaW5vci5vcmlnaW5hbCAlaW4lIGMoIkEiLCJDIiwiVCIsIkciKSkgJT4lCiAgZmlsdGVyKHRvdGFsY291bnQub3JpZ2luYWw+PTEwMCAmIG1pbm9yZnJlcS5vcmlnaW5hbD49MC4wMSAmIHRvdGFsY291bnQub3JpZ2luYWwqbWlub3JmcmVxLm9yaWdpbmFsPj01MCAmIAogICAgICAgICAgIHRvbG93ZXIoYmlub2NoZWNrLm9yaWdpbmFsKSE9ImZhbHNlIikgJT4lIGZpbHRlcigoIW50cG9zICVpbiUgcHJpbWVyX3Bvc2l0aW9uc19hbGwpKSAlPiUgCiAgZmlsdGVyKCFudHBvcyAlaW4lIDE6MjY1KSAlPiUgZmlsdGVyKCFudHBvcz4yOTY3NCkKI3dhcyB0aGUgc2FtZSBtaW5vciB2YXJpYW50IGZvdW5kIGluIHRoZSBzZWNvbmQgcmVwbGljYXRlPyBpZiBub3QsIHNldCBtaW5vciBmcmVxdWVuY3kgdG8gMCBpbiBzZWNvbmQgcmVwCm1pbm9yc190YWJsZTwtbWlub3JzX3RhYmxlICU+JSAKICBtdXRhdGUobWlub3JmcmVxLnJlc2VxPWlmX2Vsc2UobWlub3Iub3JpZ2luYWw9PW1pbm9yLnJlc2VxLCBtaW5vcmZyZXEucmVzZXEsIDApKSAlPiUgCiAgbXV0YXRlKGRldGVjdGVkX21pbm9yX2luX3JlcGw9aWZfZWxzZShtaW5vci5vcmlnaW5hbD09bWlub3IucmVzZXEsInllcyIsIm5vIikpCmBgYAoKYGBge3J9CiNob3cgd2VsbCBhcmUgbWlub3IgdmFyaWFudHMgcmVjb3ZlcmVkIGluIHNhbXBsZXMgd2l0aCBkaWZmZXJlbnQgQ3QgdmFsdWVzPwptaW5vcnNfdGFibGUgPC0gbWlub3JzX3RhYmxlICU+JSBsZWZ0X2pvaW4oc2VsZWN0KG1jb3Zfc2FtcGxlcywgTUNvVk51bWJlciwgQ1Q9SU5TVFJVTUVOVF9SRVNVTFQpKSAlPiUgCiAgbXV0YXRlKHNhbXBsZUNUX2JpbiA9IGNhc2Vfd2hlbihDVDwyNiB+ICJiZWxvdyAyNiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ1Q+PTI2JkNUPD0zNSB+IkNUIDI2LTM1IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDVD4zNSZDVDw1MCB+ImdyZWF0ZXIgdGhhbiAzNSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ1Q+MTAwfiJ1bmtub3duIiwgI2FwdGltYSBpbnN0cnVtZW50IHVzZXMgUkxVIG5vdCBDVAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzLm5hKENUKSB+ICJ1bmtub3duIikpIAooKAogIHJlcF9jdDwtbWlub3JzX3RhYmxlICU+JSAKICBnZ3Bsb3QoYWVzKHg9bWlub3JmcmVxLm9yaWdpbmFsLCB5PW1pbm9yZnJlcS5yZXNlcSwgY29sb3I9ZGV0ZWN0ZWRfbWlub3JfaW5fcmVwbCkpICsgCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcz1jKCJyZWQiLCJibGFjayIpKSArIGdlb21fcG9pbnQoYWxwaGE9MC41KSArIAogIGZhY2V0X3dyYXAofnNhbXBsZUNUX2JpbikgKyB0aGVtZV9idygpICsgbGFicyh4PSJNQUYgaW4gcmVwbGljYXRlIDEiLCB5PSJNQUYgaW4gcmVwbGljYXRlIDIiKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0iYm90dG9tIikKKSkKCmBgYAoKYGBge3J9CiNob3cgd2VsbCBhcmUgbWlub3IgdmFyaWFudHMgcmVjb3ZlcmVkIGluIHNhbXBsZXMgd2l0aCBkaWZmZXJlbnQgbWVkaWFuIGNvdmVyYWdlPwpyZXBfZGVwdGggPC0gbWlub3JzX3RhYmxlICU+JSBsZWZ0X2pvaW4oY292ZXJhZ2VfbGV2ZWxzLCBieT1jKCJNQ29WTnVtYmVyIj0ic2FtcGxlbmFtZSIpKSAlPiUgCiAgbXV0YXRlKGNvdmVyYWdlX2Jpbj1jdXQobWVkaWFuX2NvdmVyYWdlLCA0KSkgJT4lIAogIGdncGxvdChhZXMoeD1taW5vcmZyZXEub3JpZ2luYWwsIHk9bWlub3JmcmVxLnJlc2VxLCBjb2xvcj1kZXRlY3RlZF9taW5vcl9pbl9yZXBsKSkgKyAKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzPWMoInJlZCIsImJsYWNrIikpICsgZ2VvbV9wb2ludChhbHBoYT0wLjUpICsgCiAgZmFjZXRfd3JhcCh+Y292ZXJhZ2VfYmluKSArIHRoZW1lX2J3KCkgKyAKICBsYWJzKHg9Ik1BRiBpbiByZXBsaWNhdGUgMSIsIHk9Ik1BRiBpbiByZXBsaWNhdGUgMiIpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIiwgYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoY29sb3I9YygxLDAsMSwwKSkpICsgCiAgbGFicyhjYXB0aW9uPSJSZXByb2R1Y2liaWxpdHkgaW4gc2FtcGxlcyB3aXRoIGRpZmZlcmVudCBtZWRpYW4gZGVwdGhzIikKI2luIHRoZSByYW5nZSBvZiBDdCB2YWx1ZXMvY292ZXJhZ2Ugb2JzZXJ2ZWQgaGVyZSwgcmVwcm9kdWNpYmlsaXR5IHNlZW1zIG1vcmUgYXNzb2NpYXRlZCB3aXRoIEN0IHRoYW4gd2l0aCBjb3ZlcmFnZSAKYGBgCgpgYGB7cn0KI3doYXQncyB0aGUgZGlzdHJpYnV0aW9uIG9mIGRlcHRoL01BRiBpbiByZXByb2R1Y2libGUgdnMuIG5vbi1yZXByb2R1Y2libGUgbWlub3IgdmFyaWFudHM/CnJlcF9kZXB0aF9mcmVxIDwtIG1pbm9yc190YWJsZSAlPiUgZ2dwbG90KGFlcyh4PXRvdGFsY291bnQub3JpZ2luYWwsIHk9bWlub3JmcmVxLm9yaWdpbmFsKSkgKyAKICBnZW9tX3BvaW50KGFscGhhPTAuNSkgKyBmYWNldF9ncmlkKGRldGVjdGVkX21pbm9yX2luX3JlcGx+LikgKyB0aGVtZV9idygpICsgCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoY29sb3I9YygxLDAsMSwwKSkpICsgeGxhYigiU2VxIGRlcHRoIGluIHJlcCAxIikgKyAKICB5bGFiKCJNQUYgaW4gcmVwIDEiKSArIGxhYnMoY2FwdGlvbj0iUmVwcm9kdWNpYmlsaXR5IGF0IHNpdGVzIHdpdGggZGlmZmVyZW50IGRlcHRoIGFuZCBNQUYiKQojZGVwdGggYW5kIGZyZXF1ZW5jeSBvZiBtaW5vciB2YXJpYW50cyBpcyBhbHNvIG5vdCB2ZXJ5IGRpZmZlcmVudCBiZXR3ZWVuIHJlcHJvZHVjaWJsZSBhbmQgbm9uLXJlcHJvZHVjaWJsZSB2YXJpYW50cwpgYGAKCmBgYHtyfQpyZXBfbXV0YXRpb25zIDwtIG1pbm9yc190YWJsZSAlPiUgZmlsdGVyKGRldGVjdGVkX21pbm9yX2luX3JlcGw9PSJ5ZXMiKSAKbm9ucmVwX211dGF0aW9ucyA8LSBtaW5vcnNfdGFibGUgJT4lIGZpbHRlcihkZXRlY3RlZF9taW5vcl9pbl9yZXBsPT0ibm8iKSAKCmEgPC0gdGFibGUocmVwX211dGF0aW9ucyRtYWpvci5vcmlnaW5hbCwgcmVwX211dGF0aW9ucyRtaW5vci5vcmlnaW5hbCkgJT4lIAogIGRhdGEuZnJhbWUoKSAlPiUgZ2dwbG90KGFlcyh4PVZhcjEsIHk9VmFyMiwgZmlsbD1GcmVxKSkgKyAKICBnZW9tX3RpbGUoY29sb3VyID0gImJsYWNrIikgKyAjIGdyaWQgY29sb3VyCiAgc2NhbGVfZmlsbF9ncmFkaWVudChsb3cgPSAid2hpdGUiLAogICAgICAgICAgICAgICAgICAgICAgaGlnaCA9ICJzdGVlbGJsdWUiKSArCiAgdGhlbWVfbWluaW1hbCgpICsgbGFicyhmaWxsID0gIk51bWJlciIsCiAgICAgICB4ID0gIkNvbnNlbnN1cyBhbGxlbGUiLAogICAgICAgeSA9ICJNaW5vciBhbGxlbGUiLCBjYXB0aW9uPSJSZXByb2R1Y2libGUgbWlub3IgdmFyaWFudHMiKQoKYiA8LSB0YWJsZShub25yZXBfbXV0YXRpb25zJG1ham9yLm9yaWdpbmFsLCBub25yZXBfbXV0YXRpb25zJG1pbm9yLm9yaWdpbmFsKSAlPiUgCiAgZGF0YS5mcmFtZSgpICU+JSBnZ3Bsb3QoYWVzKHg9VmFyMSwgeT1WYXIyLCBmaWxsPUZyZXEpKSArIAogIGdlb21fdGlsZShjb2xvdXIgPSAiYmxhY2siKSArIAogIHNjYWxlX2ZpbGxfZ3JhZGllbnQobG93ID0gIndoaXRlIiwKICAgICAgICAgICAgICAgICAgICAgIGhpZ2ggPSAic3RlZWxibHVlIikgKwogIHRoZW1lX21pbmltYWwoKSArIGxhYnMoZmlsbCA9ICJOdW1iZXIiLAogICAgICAgeCA9ICJDb25zZW5zdXMgYWxsZWxlIiwKICAgICAgIHkgPSAiTWlub3IgYWxsZWxlIiwgY2FwdGlvbj0iTm9uLXJlcHJvZHVjaWJsZSBtaW5vciB2YXJpYW50cyIpCgpyZXBfbnVjbGVvdGlkZXMgPC0gY293cGxvdDo6cGxvdF9ncmlkKGEsIGIsIG5jb2w9MikKCiNTVVBQIEZJRyA4CnJlcF9udWNsZW90aWRlcwoKYGBgCgoKYGBge3J9CnJlcF9pbmRpdl9zYW1wbGVzIDwtIG1pbm9yc190YWJsZSAlPiUgZ2dwbG90KGFlcyh4PW1pbm9yZnJlcS5vcmlnaW5hbCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeT1taW5vcmZyZXEucmVzZXEsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9yPWRldGVjdGVkX21pbm9yX2luX3JlcGwpKSArIAogIGdlb21fcG9pbnQoYWxwaGE9MC41KSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXM9YygicmVkIiwiYmxhY2siKSkgKyAKICBmYWNldF93cmFwKENUfk1Db1ZOdW1iZXIpICsgdGhlbWVfYncoKSArIHhsYWIoIk1BRiBpbiByZXBsaWNhdGUgMSIpICsgCiAgeWxhYigiTUFGIGluIHJlcGxpY2F0ZSAyIikgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiLCBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChjb2xvcj1jKDEsMCwxLDApKSkKYGBgCgpgYGB7ciwgZmlnLmhlaWdodCA9IDEwfQojU1VQUCBGSUcgMQpwbG90X2dyaWQoCiAgcGxvdF9ncmlkKHJlcF9jdCwgCiAgICAgICAgICAgIHBsb3RfZ3JpZChyZXBfZGVwdGgsIHJlcF9kZXB0aF9mcmVxLCBuY29sPTIsIHJlbF93aWR0aHM9YygxLjIsMSksIAogICAgICAgICAgICAgICAgICAgICAgbGFiZWxzPWMoImIiLCJjIikpLCBucm93PTIsIGxhYmVscz1jKCJhIixOQSkpLCAKICByZXBfaW5kaXZfc2FtcGxlcywgbGFiZWxzPWMoTkEsICJkIiksIHJlbF93aWR0aHM9YygxLjEsMSkpCmBgYAoKCldpbGwgbGltaXQgYW5hbHlzZXMgdG8gc2FtcGxlcyB3aXRoIENUPDI2LCB3aGVyZSB3ZSBhcmUgbW9yZSBjb25maWRlbnQgaW4gcmVwcm9kdWNpYmlsaXR5IG9mIG1pbm9yIHZhcmlhbnQKCgpgYGB7cn0Kc2FtcGxlc19uX3ZhciAlPiUgZmlsdGVyKElOU1RSVU1FTlRfUkVTVUxUPDI2ICYgbl92YXIgPCAzMCkgJT4lIHB1bGwobl92YXIpICU+JSBxdWFudGlsZShjKDAuNSwwLjcpKQpgYGAKCmBgYHtyfQpzYW1wbGVzX3RvX2FuYWx5emUgPC0gc2FtcGxlc19uX3ZhciAlPiUgZmlsdGVyKElOU1RSVU1FTlRfUkVTVUxUPDI2KSAlPiUgcHVsbChNQ29WTnVtYmVyKQpsaW5lYWdlc19maWd1cmUgPC0gbWNvdl9zYW1wbGVzX2ZpbHRlcmVkICU+JSAKICBmaWx0ZXIoTUNvVk51bWJlciAlaW4lIHNhbXBsZXNfdG9fYW5hbHl6ZSkgJT4lIAogIG11dGF0ZSh2YXJpYW50PWNhc2Vfd2hlbihzdGFydHNXaXRoKHNjb3JwaW9fY2FsbCwiRGVsdGEiKSB+ICJEZWx0YSIsCiAgICAgICAgc3RhcnRzV2l0aChzY29ycGlvX2NhbGwsIkFscGhhIikgfiAiQWxwaGEiLAogICAgICAgICEoc3RhcnRzV2l0aChzY29ycGlvX2NhbGwsIkRlbHRhIil8CiAgICAgICAgICAgIHN0YXJ0c1dpdGgoc2NvcnBpb19jYWxsLCJBbHBoYSIpKSB+ICJvdGhlciBsaW5lYWdlcyIpKSAlPiUKICBtdXRhdGUodmFyaWFudD1pZl9lbHNlKGxpbmVhZ2UgPT0gIkIuMS4yIiwiQi4xLjIiLHZhcmlhbnQpKSAlPiUKICBnZ3Bsb3QoYWVzKHg9Q09MTEVDVElPTl9EVCkpICsgZ2VvbV9iYXIoYWVzKGZpbGw9dmFyaWFudCkpICsgdGhlbWVfYncoKSArIAogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcz1jKCIjMDBBMDhBIiwgIiNGMkFEMDAiLCAiI0Y5ODQwMCIsICIjNUJCQ0Q2IikpICsgCiAgeGxhYigiQ29sbGVjdGlvbiBkYXRlIikgKyB5bGFiKCJOby4gc2FtcGxlcyIpICsgCiAgZ2d0aXRsZShwYXN0ZTAoJ0ZpbmFsIHNhbXBsZSBzZXQsIENUPDI2LCBuID0nLGxlbmd0aChzYW1wbGVzX3RvX2FuYWx5emUpKSkgKyAKICBzY2FsZV94X2RhdGUobWlub3JfYnJlYWtzPSIxIG1vbnRoIikKCiNTVVBQIEZJRyAyCmxpbmVhZ2VzX2ZpZ3VyZQpgYGAKCmBgYHtyfQpzYW1wbGVzX25fdmFyICU+JSBmaWx0ZXIoSU5TVFJVTUVOVF9SRVNVTFQ8MjYpICU+JSBwdWxsKG5fdmFyKSAlPiUgc3VtbWFyeSgpCmBgYAoKYGBge3J9CiNwbG90X2dyaWQoY292ZXJhZ2VfcHJlX2ZpbHRlcmluZywgY3RfaW5jbHVzaW9uLCBuY29sPTIsIGxhYmVscz1jKCJhIiwiYiIpKQpgYGAKCmBgYHtyfQptaW5vcl9zaXRlc19sb3djdDwtbWlub3JfdmFyaWFudF9zaXRlc190aHJlc2hvbGQgJT4lIGxlZnRfam9pbihtY292X3NhbXBsZXNfZmlsdGVyZWQpICU+JSAKICBmaWx0ZXIoSU5TVFJVTUVOVF9SRVNVTFQ8MjYpIApgYGAKCgojIFdoYXQga2luZHMgb2YgcnVuLXNwZWNpZmljIGVmZmVjdHMgZG8gd2Ugc2VlIGV2ZW4gYWZ0ZXIgZmlsdGVyaW5nIGZvciBoaWdoLXF1YWxpdHkgc2FtcGxlcz8KCmBgYHtyfQooKG5fdmFyX2J5X3J1biA8LSBzYW1wbGVzX25fdmFyICU+JSBmaWx0ZXIoSU5TVFJVTUVOVF9SRVNVTFQgPCAyNiAmIG5fdmFyIDwgMzApICU+JSAKICAgIGdncGxvdChhZXMoeD1ydW4sIHk9bl92YXIpKSArIGdlb21fYm94cGxvdCgpICsgdGhlbWVfYncoKSArIAogICAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCkpICsgeGxhYigiUnVuIikgKyB5bGFiKCJOby4gbWlub3IgdmFyaWFudHMiKSkpCmBgYAoKYGBge3J9CiNhcmUgcnVuIGVmZmVjdHMgcmVsYXRlZCB0byBzZXF1ZW5jaW5nIGRlcHRoPwpuX3Zhcl9ieV9jb3ZlcmFnZTwtc2FtcGxlc19uX3ZhciAlPiUgZmlsdGVyKElOU1RSVU1FTlRfUkVTVUxUPDI2KSAlPiUgZ2dwbG90KGFlcyh4PW1lZGlhbl9jb3ZlcmFnZSwgeT1uX3ZhcikpICsgZ2VvbV9wb2ludChhbHBoYT0wLjUpICsgZ2VvbV9zbW9vdGgoKSArIHRoZW1lX2J3KCkgKyB4bGFiKCJTYW1wbGUgbWVkaWFuIGNvdmVyYWdlIikgKyB5bGFiKCJOby4gbWlub3IgdmFyaWFudHMgaW4gc2FtcGxlIikKI25vdCBvbiB0aGUgaW5kaXZpZHVhbCBzYW1wbGUgbGV2ZWwKYGBgCgpgYGB7cn0KI2lzIGF2ZXJhZ2UgbWlub3IgdmFyaWFudCByaWNobmVzcyBpbiBhIHJ1biByZWxhdGVkIHRvIGF2ZXJhZ2UgZGVwdGggb2YgY292ZXJhZ2UgaW4gdGhlIHJ1bj8Kbl92YXJfZGVwdGhfYXZlcmFnZXM8LXNhbXBsZXNfbl92YXIgJT4lIGZpbHRlcihJTlNUUlVNRU5UX1JFU1VMVDwyNikgJT4lIGdyb3VwX2J5KHJ1bikgJT4lIHN1bW1hcmlzZShtZWRpYW5fbl92YXI9bWVkaWFuKG5fdmFyKSwgbWVkaWFuX3NhbXBsZV9jb3ZlcmFnZT1tZWRpYW4obWVkaWFuX2NvdmVyYWdlKSwgbWVkaWFuX2N0PW1lZGlhbihJTlNUUlVNRU5UX1JFU1VMVCkpICU+JSBnZ3Bsb3QoYWVzKHg9bWVkaWFuX3NhbXBsZV9jb3ZlcmFnZSwgeT1tZWRpYW5fbl92YXIpKSArIGdlb21fcG9pbnQoKSArIHRoZW1lX2J3KCkgKyB4bGFiKCJSdW4tbGV2ZWwgbWVkaWFuIG9mIG1lZGlhbiBjb3ZlcmFnZSIpICsgeWxhYigiTWVkaWFuIG5vLiBtaW5vciB2YXJpYW50cyBvZiBzYW1wbGVzIGluIHJ1biIpICsgZ2VvbV9zbW9vdGgobWV0aG9kPWxtKSAKYGBgCgpgYGB7cn0Kc2FtcGxlc19uX3ZhciAlPiUgZmlsdGVyKElOU1RSVU1FTlRfUkVTVUxUPDI2KSAlPiUgZmlsdGVyKHJ1bj09IlJ1bl85MCIpICU+JSBnZ3Bsb3QoYWVzKHg9bWVkaWFuX2NvdmVyYWdlLCB5PW5fdmFyKSkgKyBnZW9tX3BvaW50KCkgKyBnZ3RpdGxlKCJSdW4gOTAgLSB2ZXJ5IGhpZ2ggYXZlcmFnZSBjb3ZlcmFnZSIpICsgdGhlbWVfYncoKSArIGdlb21faGxpbmUoeWludGVyY2VwdD0xMCwgbGluZXR5cGU9ImRvdHRlZCIpCmBgYAoKYGBge3J9CnNhbXBsZXNfbl92YXIgJT4lIGZpbHRlcihJTlNUUlVNRU5UX1JFU1VMVDwyNikgJT4lIGZpbHRlcihydW49PSJSdW5fMjkiKSAlPiUgZ2dwbG90KGFlcyh4PW1lZGlhbl9jb3ZlcmFnZSwgeT1uX3ZhcikpICsgZ2VvbV9wb2ludCgpICsgZ2d0aXRsZSgiUnVuIDI5IC0gbG93ZXIgYXZlcmFnZSBjb3ZlcmFnZSIpICsgdGhlbWVfYncoKSArIGdlb21faGxpbmUoeWludGVyY2VwdD0xMCwgbGluZXR5cGU9ImRvdHRlZCIpCmBgYAoKCmBgYHtyfQojYXJlIHRoZSBydW4tc3BlY2lmaWMgZGlmZmVyZW5jZXMgaW4gY292ZXJhZ2Ugc3Ryb25nZXIgaW4gc2FtcGxlcyB0aGF0IHdlcmUgaW5jbHVkZWQgb3IgdGhhdCB3ZXJlbid0IGluY2x1ZGVkPwptY292X3NhbXBsZXMgJT4lIG11dGF0ZShocV9zYW1wbGU9aWZfZWxzZShNQ29WTnVtYmVyICVpbiUgbWlub3Jfc2l0ZXNfbG93Y3QkTUNvVk51bWJlciwgImhxIiwiZXhjbHVkZWQiKSkgJT4lICBnZ3Bsb3QoYWVzKHg9cnVuLCB5PW1lZGlhbl9jb3ZlcmFnZSkpICsgZ2VvbV9ib3hwbG90KCkgK3RoZW1lX2J3KCkgKyB0aGVtZShheGlzLnRleHQueD1lbGVtZW50X3RleHQoYW5nbGU9OTApKSArIGZhY2V0X2dyaWQoaHFfc2FtcGxlfi4pIApgYGAKYGBge3J9CiNTVVBQIEZJRyAzCnBsb3RfZ3JpZChuX3Zhcl9ieV9ydW4sIHBsb3RfZ3JpZChuX3Zhcl9ieV9jb3ZlcmFnZSwgbl92YXJfZGVwdGhfYXZlcmFnZXMsIG5yb3c9MiksIG5jb2w9MiwgcmVsX3dpZHRocyA9IGMoMiwxKSwgbGFiZWxzPWMoImEiLCJiIikpCmBgYAo=